/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package be.ugent.medirem.persistence.facade;

import be.ugent.medirem.persistence.entity.Dosage;
import be.ugent.medirem.persistence.entity.GeneralPractitioner;
import be.ugent.medirem.persistence.entity.Medication;
import be.ugent.medirem.persistence.entity.Patient;
import be.ugent.medirem.persistence.entity.Prescription;
import be.ugent.medirem.persistence.entity.Unit;
import be.ugent.medirem.persistence.entity.details.PrescriptionDetails;
import be.ugent.medirem.persistence.entity.values.PrescriptionValues;
import be.ugent.medirem.persistence.exception.EntityNotFoundException;
import be.ugent.medirem.persistence.util.EntityDetailsToEntity;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Thomas Roelens
 */
@Stateless
public class PrescriptionDaoBean implements PrescriptionDaoLocal {

    @EJB
    private UnitDaoLocal unitDaoBean;
    @PersistenceContext
    private EntityManager em;

    public void addPrescription(Long patientId, Long prescriptionId) {
        Patient patient = null;
        Prescription prescription = null;

        if (patientId == null) {
            throw new IllegalArgumentException("Patient id is null");
        }
        try {
            patient = em.find(Patient.class, patientId);
            prescription = em.find(Prescription.class, prescriptionId);

            if (patient == null || prescription == null) {
                throw new EntityNotFoundException();
            } else {
                patient.addPrescription(prescription);
                em.merge(patient);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public List<PrescriptionDetails> getPrescriptions(Long patientId) {
        Patient patient = null;
        List<PrescriptionDetails> prescriptions = new ArrayList<PrescriptionDetails>();

        if (patientId == null) {
            throw new IllegalArgumentException("Patient id is null");
        }
        try {
            patient = em.find(Patient.class, patientId);

            if (patient == null) {
                throw new EntityNotFoundException();
            } else {
                for (Prescription p : patient.getPrescriptions()) {
                    prescriptions.add(EntityDetailsToEntity.prescriptionToDetails(p));
                }
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }

        return prescriptions;
    }

    public void removePrescriptionFromPatient(Long patientId, Long prescriptionId) {
        Patient patient = null;
        Prescription prescription = null;

        if (patientId == null) {
            throw new IllegalArgumentException("Patient id is null");
        }
        try {
            patient = em.find(Patient.class, patientId);
            prescription = em.find(Prescription.class, prescriptionId);

            if (patient == null || prescription == null) {
                throw new EntityNotFoundException();
            } else {
                patient.removePrescription(prescription);
                em.merge(patient);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public void persist(Object object) {
        em.persist(object);
    }

    public Long create(PrescriptionValues p) throws IllegalArgumentException {
        if (p.getMedicationId() == null) {
            throw new IllegalArgumentException("Medication id can't be null");
        }
        if (p.getGpId() == null) {
            throw new IllegalArgumentException("GP id can't be null");
        }

        Prescription pre = null;

        try {
            Unit ud = em.find(Unit.class, unitDaoBean.getUnitId(p.getDosageUnit()));

            Dosage d = new Dosage();
            d.setDosage(p.getDosageDosage());
            d.setUnit(ud);
            d.setIsFixed(p.isDosageIsFixed());

            Medication medication = em.find(Medication.class, p.getMedicationId());
            GeneralPractitioner gp = em.find(GeneralPractitioner.class, p.getGpId());
            pre = new Prescription(medication, gp, p.getFrequency(), d, p.getStartTime(), p.getEndTime(), p.getRemarks());

            em.persist(d);
            em.persist(pre);

        } catch (Exception ex) {
            throw new EJBException(ex);
        }

        return pre.getId();
    }

    public void remove(Long id) throws javax.persistence.EntityNotFoundException, IllegalArgumentException {
        if (id == null) {
            throw new IllegalArgumentException("Prescription id can't be null");
        }
        try {
            Prescription p = em.find(Prescription.class, id);
            if (p == null) {
                throw new javax.persistence.EntityNotFoundException();
            }
            em.remove(p);
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public PrescriptionDetails getDetails(Long prescriptionId) throws EntityNotFoundException, IllegalArgumentException {
        if (prescriptionId == null) {
            throw new IllegalArgumentException("Prescription id is null");
        }
        Prescription p = em.find(Prescription.class, prescriptionId);
        if (p == null) {
            throw new EntityNotFoundException("Prescription not found with id " + prescriptionId);
        }
        return convert(p);
    }

    public void update(Long prescriptionId, PrescriptionValues d) throws EntityNotFoundException, IllegalArgumentException {
        if (prescriptionId == null) {
            throw new IllegalArgumentException("Prescription id is null");
        }
        Prescription p = em.find(Prescription.class, prescriptionId);
        if (p == null) {
            throw new EntityNotFoundException("Prescription not found with id " + prescriptionId);
        }

        if (d.getDosageDosage() != 0) {
            p.getDosage().setDosage(d.getDosageDosage());
        }
        if (d.getFrequency() != 0) {
            p.setFrequency(d.getFrequency());
        }
        if (d.getEndTime() != null) {
            p.setEndTime(d.getEndTime());
        }
        if (d.getRemarks() != null) {
            p.setRemarks(d.getRemarks());
        }
        if (d.getStartTime() != null) {
            p.setStartTime(d.getStartTime());
        }
        // TODO eventueel medication, gp wijzigen
        em.merge(p);
    }

    private PrescriptionDetails convert(Prescription p) {
        if (p == null) {
            return null;
        } else {
            return EntityDetailsToEntity.prescriptionToDetails(p);
        }
    }
}
